import React, { useEffect, useRef, useState, useCallback } from 'react';
import { View, Text } from '@tarojs/components';
import Taro from '@tarojs/taro';
import * as THREE from 'three';
// @ts-ignore
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
// 添加WebXR支持
// @ts-ignore
import { ARButton } from 'three/examples/jsm/webxr/ARButton';
// @ts-ignore
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory';
// 添加OrbitControls用于摄像机控制
// @ts-ignore
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import './llz.scss';
import * as tf from '@tensorflow/tfjs';
import * as handpose from '@tensorflow-models/handpose';
// 导入正确的全景背景图片
import phoneShopImage from '../../module/42-114104_68b272d0769fa.tiles/preview.jpg';
import frontImage from '../../module/42-114104_68b272d0769fa.tiles/f/l1_f_1_1.jpg';
import backImage from '../../module/42-114104_68b272d0769fa.tiles/b/l1_b_1_1.jpg';
import upImage from '../../module/42-114104_68b272d0769fa.tiles/u/l1_u_1_1.jpg';
import downImage from '../../module/42-114104_68b272d0769fa.tiles/d/l1_d_1_1.jpg';
import rightImage from '../../module/42-114104_68b272d0769fa.tiles/r/l1_r_1_1.jpg';
import leftImage from '../../module/42-114104_68b272d0769fa.tiles/l/l1_l_1_1.jpg';

// 定义手机部件类型
interface PhonePart {
  id: string;
  name: string;
  mesh: THREE.Object3D;
  originalPosition: THREE.Vector3;
  disassemblyOrder: number;
  animationOffset: THREE.Vector3;
}

// 检测是否为小程序环境
const isMiniProgram = () => {
  return process.env.TARO_ENV === 'weapp' || 
         process.env.TARO_ENV === 'swan' || 
         process.env.TARO_ENV === 'alipay' || 
         process.env.TARO_ENV === 'tt' || 
         process.env.TARO_ENV === 'qq';
};

const PhoneModel: React.FC = () => {
  const mountRef = useRef<HTMLDivElement>(null);
  const sceneRef = useRef<THREE.Scene | null>(null);
  const rendererRef = useRef<THREE.WebGLRenderer | null>(null);
  const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);
  const modelRef = useRef<THREE.Group | null>(null);
  const animationIdRef = useRef<number | null>(null);
  const raycasterRef = useRef<THREE.Raycaster>(new THREE.Raycaster());
  const mouseRef = useRef<THREE.Vector2>(new THREE.Vector2());
  const arButtonRef = useRef<HTMLElement | null>(null); // 修改类型为 HTMLElement
  const controllerRef = useRef<THREE.XRTargetRaySpace | null>(null);
  // 添加OrbitControls引用
  const controlsRef = useRef<OrbitControls | null>(null);
  const [audioContext, setAudioContext] = useState<AudioContext | null>(null);
  
  // 手机模型旋转状态
  const phoneRotationRef = useRef({ x: 0, y: 0 });

  // 拆解状态管理
  const [disassemblyStep, setDisassemblyStep] = useState(0);
  const [isARMode, setIsARMode] = useState(false);
  const [isAnimating, setIsAnimating] = useState(false);
  const [modelLoaded, setModelLoaded] = useState(false);
  // 移除 showModel 状态，直接显示模型
  const phonePartsRef = useRef<PhonePart[]>([]);
  
  // 部件详细信息状态
  const [selectedPart, setSelectedPart] = useState<PhonePart | null>(null);
  const [showPartInfo, setShowPartInfo] = useState(false);
  
  // 拖拽状态
  const [hasDragged, setHasDragged] = useState(false);

  const [handModel, setHandModel] = useState<any>(null);
  const videoRef = useRef<HTMLVideoElement>(null);

  const particleSystemRef = useRef<THREE.Points | null>(null);

  // 声明 renderLoop 变量
  let renderLoop: (() => void) | null = null;

  // AR 控制器事件处理函数
  const onSelectStart = useCallback((event: any) => {
    console.log('AR控制器选择开始', event);
    // 触发拆解动画
    if (!isAnimating && disassemblyStep < phonePartsRef.current.length) {
      const nextStep = disassemblyStep + 1;
      setDisassemblyStep(nextStep);
      animateDisassembly(nextStep);
    }
    
    // 触觉反馈（如果支持）
    if (event.target && event.target.gamepad && event.target.gamepad.hapticActuators) {
      event.target.gamepad.hapticActuators[0]?.pulse(0.5, 100);
    }
  }, [disassemblyStep, isAnimating]);

  const onSelectEnd = useCallback((event: any) => {
    console.log('AR控制器选择结束', event);
  }, []);

  const createParticleSystem = () => {
    const particleCount = 1000;
    const particles = new THREE.BufferGeometry();
    const positions = new Float32Array(particleCount * 3);
    const colors = new Float32Array(particleCount * 3);

    for (let i = 0; i < particleCount; i++) {
      positions[i * 3] = (Math.random() - 0.5) * 10;
      positions[i * 3 + 1] = (Math.random() - 0.5) * 10;
      positions[i * 3 + 2] = (Math.random() - 0.5) * 10;

      colors[i * 3] = Math.random();
      colors[i * 3 + 1] = Math.random();
      colors[i * 3 + 2] = Math.random();
    }

    particles.setAttribute('position', new THREE.BufferAttribute(positions, 3));
    particles.setAttribute('color', new THREE.BufferAttribute(colors, 3));

    const material = new THREE.PointsMaterial({
      size: 0.05,
      vertexColors: true,
      transparent: true,
      opacity: 0.6
    });

    const particleSystem = new THREE.Points(particles, material);
    particleSystemRef.current = particleSystem;

    return particleSystem;
  };

  // 触发粒子爆炸效果
  const triggerParticleExplosion = (position: THREE.Vector3) => {
    if (!particleSystemRef.current || !sceneRef.current) return;

    const explosionParticles = createParticleSystem();
    explosionParticles.position.copy(position);
    sceneRef.current.add(explosionParticles);

    // 动画粒子扩散
    const startTime = Date.now();
    const animateExplosion = () => {
      const elapsed = Date.now() - startTime;
      const progress = elapsed / 2000; // 2秒动画

      if (progress < 1) {
        explosionParticles.scale.setScalar(1 + progress * 2);
        explosionParticles.material.opacity = 0.6 * (1 - progress);
        requestAnimationFrame(animateExplosion);
      } else {
        sceneRef.current?.remove(explosionParticles);
      }
    };

    animateExplosion();
  };

  // 初始化手势识别
  const initHandTracking = async () => {
    try {
      await tf.ready();
      const model = await handpose.load();
      setHandModel(model);
  
      // 启动摄像头
      const stream = await navigator.mediaDevices.getUserMedia({ video: true });
      if (videoRef.current) {
        videoRef.current.srcObject = stream;
        
        // 等待视频元数据加载完成
        videoRef.current.onloadedmetadata = () => {
          console.log('视频元数据加载完成，尺寸:', videoRef.current?.videoWidth, 'x', videoRef.current?.videoHeight);
          // 确保视频有有效尺寸后再开始检测
          if (videoRef.current && videoRef.current.videoWidth > 0 && videoRef.current.videoHeight > 0) {
            detectHands();
          }
        };
        
        videoRef.current.play();
      }
    } catch (error) {
      console.error('手势识别初始化失败:', error);
    }
  };
  
  // 手势检测
  const detectHands = async () => {
    // 添加视频尺寸检查
    if (handModel && videoRef.current && 
        videoRef.current.videoWidth > 0 && 
        videoRef.current.videoHeight > 0) {
      try {
        const predictions = await handModel.estimateHands(videoRef.current);
  
        if (predictions.length > 0) {
          const hand = predictions[0];
          // 检测抓取手势
          if (isGraspGesture(hand.landmarks)) {
            // 执行拆解动作
            if (!isAnimating && disassemblyStep < phonePartsRef.current.length) {
              const nextStep = disassemblyStep + 1;
              setDisassemblyStep(nextStep);
              animateDisassembly(nextStep);
            }
          }
        }
      } catch (error) {
        console.error('手势检测错误:', error);
      }
    }
  
    requestAnimationFrame(detectHands);
  };

  // 判断是否为抓取手势
  const isGraspGesture = (landmarks: number[][]) => {
    // 简单的抓取手势检测逻辑
    const thumb = landmarks[4];
    const index = landmarks[8];
    const middle = landmarks[12];

    const distance = Math.sqrt(
      Math.pow(thumb[0] - index[0], 2) + Math.pow(thumb[1] - index[1], 2)
    );

    return distance < 30; // 阈值可调整
  };

  // 小程序环境检测和拦截
  useEffect(() => {
    if (isMiniProgram()) {
      Taro.showModal({
        title: '访问限制',
        content: '此页面仅支持在H5环境下访问，小程序暂不支持3D模型功能',
        showCancel: false,
        success: () => {
          // 尝试返回上一页，如果失败则跳转到首页
          Taro.navigateBack({
            fail: () => {
              Taro.reLaunch({
                url: '/pages/index/index'
              });
            }
          });
        }
      });
      return;
    }
    
    initHandTracking();
    // 移除这里的 detectHands() 调用，改为在视频加载完成后调用
  }, []);
  // 添加音效支持
  const playSound = (frequency: number, duration: number) => {
    if (!audioContext) return;

    const oscillator = audioContext.createOscillator();
    const gainNode = audioContext.createGain();

    oscillator.connect(gainNode);
    gainNode.connect(audioContext.destination);

    oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);
    gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
    gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + duration);

    oscillator.start(audioContext.currentTime);
    oscillator.stop(audioContext.currentTime + duration);
  };

  // 触觉反馈
  const triggerHapticFeedback = () => {
    if ('vibrate' in navigator) {
      navigator.vibrate([50, 30, 50]);
    }
  };

  // 修改拆解动画函数，添加反馈
  const animateDisassembly = useCallback((targetStep: number) => {
    if (isAnimating || phonePartsRef.current.length === 0) {
      return;
    }
    // 播放拆解音效
    playSound(800 + targetStep * 100, 0.2);
    // 触觉反馈
    triggerHapticFeedback();

    console.log(`开始拆解动画，目标步骤: ${targetStep}`);
    setIsAnimating(true);
    const animationDuration = 1500;
    const startTime = Date.now();

    // 获取需要移动的部件
    const partsToAnimate = phonePartsRef.current.filter(
      part => part.disassemblyOrder <= targetStep
    );
    

    console.log(`需要动画的部件数量: ${partsToAnimate.length}`);

    const animate = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / animationDuration, 1);

      // 使用缓动函数实现平滑动画
      const easeOutCubic = 1 - Math.pow(1 - progress, 3);

      try {
        partsToAnimate.forEach(part => {
          if (part.disassemblyOrder <= targetStep && part.mesh) {
            const targetPosition = part.originalPosition.clone().add(
              part.animationOffset.clone().multiplyScalar(easeOutCubic)
            );
            part.mesh.position.copy(targetPosition);

            // 添加轻微的旋转效果
            if (part.name !== 'mainBoard') {
              part.mesh.rotation.x = easeOutCubic * 0.1;
              part.mesh.rotation.y = easeOutCubic * 0.05;
            }
          }
        });
      } catch (error) {
        console.error('动画执行错误:', error);
        setIsAnimating(false);
        return;
      }

      if (progress < 1) {
        requestAnimationFrame(animate);
      } else {
        setIsAnimating(false);
        console.log('拆解动画完成');
      }
    };

    animate();
  }, [isAnimating, audioContext]);

  useEffect(() => {
    // 初始化音频上下文
    const initAudio = () => {
      try {
        const ctx = new (window.AudioContext || (window as any).webkitAudioContext)();
        setAudioContext(ctx);
      } catch (e) {
        console.log('音频不支持');
      }
    };

    initAudio();
    console.log('动画被阻止：', { isAnimating, partsCount: phonePartsRef.current.length });
    return;
  }, []);


  // 重置动画函数 - 移到组件级别
  const resetAnimation = useCallback(() => {
    if (isAnimating) return;

    setIsAnimating(true);
    const animationDuration = 1000;
    const startTime = Date.now();

    const animate = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / animationDuration, 1);
      const easeInCubic = progress * progress * progress;

      phonePartsRef.current.forEach(part => {
        const currentPos = part.mesh.position.clone();
        const targetPos = part.originalPosition.clone();
        part.mesh.position.lerpVectors(currentPos, targetPos, easeInCubic);

        // 重置旋转
        part.mesh.rotation.x *= (1 - easeInCubic);
        part.mesh.rotation.y *= (1 - easeInCubic);
      });

      if (progress < 1) {
        requestAnimationFrame(animate);
      } else {
        setIsAnimating(false);
        setDisassemblyStep(0);
      }
    };

    animate();
  }, [isAnimating]);

  useEffect(() => {
    if (!mountRef.current) return;

    // 创建场景
    const scene = new THREE.Scene();
    
    // 设置默认背景色（避免黑色背景）
    scene.background = new THREE.Color(0xf0f0f0);
    
    // 使用简单的全景图片作为背景
    const textureLoader = new THREE.TextureLoader();
    
    // 加载全景图片
    textureLoader.load(
      phoneShopImage,
      (texture) => {
        console.log('全景图片加载成功');
        
        // 设置纹理的包装和过滤方式
        texture.wrapS = THREE.RepeatWrapping;
        texture.wrapT = THREE.ClampToEdgeWrapping;
        texture.minFilter = THREE.LinearFilter;
        texture.magFilter = THREE.LinearFilter;
        
        // 创建球形几何体用于全景背景
        const sphereGeometry = new THREE.SphereGeometry(50, 64, 32);
        
        // 翻转球体内表面以显示纹理
        sphereGeometry.scale(-1, 1, 1);
        
        // 创建材质
        const sphereMaterial = new THREE.MeshBasicMaterial({
          map: texture,
          side: THREE.BackSide // 只显示内表面
        });
        
        // 创建全景球体
        const panoramaSphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
        // 旋转背景图180度，与手机模型保持一致的视角
        panoramaSphere.rotation.y = Math.PI;
        scene.add(panoramaSphere);
        
        // 设置背景为黑色
        scene.background = new THREE.Color(0x000000);
      },
      (progress) => {
        console.log('全景图片加载进度:', progress);
      },
      (error) => {
        console.error('全景图片加载失败:', error);
        scene.background = new THREE.Color(0xe0e0e0);
      }
    );
    
    // 使用立方体贴图作为背景（修复版本）
    const cubeTextureLoader = new THREE.CubeTextureLoader();
    
    // 添加路径前缀，确保正确加载
    cubeTextureLoader.setPath('');
    
    const cubeTexture = cubeTextureLoader.load([
      rightImage,  // positive x
      leftImage,   // negative x
      upImage,     // positive y
      downImage,   // negative y
      frontImage,  // positive z
      backImage    // negative z
    ], 
    () => {
      // 加载成功回调
      console.log('立方体贴图加载成功');
      scene.background = cubeTexture;
    },
    (progress) => {
      // 加载进度回调
      console.log('立方体贴图加载进度:', progress);
    },
    (error) => {
      // 加载失败回调
      console.error('立方体贴图加载失败:', error);
      // 回退到简单背景
      scene.background = new THREE.Color(0xf0f0f0);
    });
    
    // 添加展示台（现代白色设计）
    const platformGeometry = new THREE.CylinderGeometry(1.8, 2.0, 0.4, 32);
    const platformMaterial = new THREE.MeshPhongMaterial({ 
      color: 0xffffff,
      shininess: 200,
      transparent: false,
      opacity: 1.0
    });
    const platform = new THREE.Mesh(platformGeometry, platformMaterial);
    platform.position.y = -1.8;
    platform.castShadow = true;
    platform.receiveShadow = true;
    scene.add(platform);
    
    // 添加平台边缘装饰
    const platformEdgeGeometry = new THREE.TorusGeometry(1.5, 0.05, 8, 32);
    const platformEdgeMaterial = new THREE.MeshPhongMaterial({ 
      color: 0x7f8c8d,
      shininess: 50
    });
    const platformEdge = new THREE.Mesh(platformEdgeGeometry, platformEdgeMaterial);
    platformEdge.position.set(0, -0.75, 0);
    platformEdge.rotation.x = Math.PI / 2;
    scene.add(platformEdge);

    sceneRef.current = scene;

    // 创建相机
    const camera = new THREE.PerspectiveCamera(
      75,
      mountRef.current.clientWidth / mountRef.current.clientHeight,
      0.1,
      1000
    );
    // 修改初始视角：摄像机视角旋转180度
    camera.position.set(0, 2, -8); // 从背面观看，距离更远
    camera.lookAt(0, -0.5, 0); // 保持观看点不变
    cameraRef.current = camera;

    // 创建渲染器
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    rendererRef.current = renderer;
    mountRef.current.appendChild(renderer.domElement);

    // 创建OrbitControls用于摄像机控制
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true; // 启用阻尼效果
    controls.dampingFactor = 0.05;
    controls.screenSpacePanning = false;
    controls.minDistance = 4; // 稍微减少最小距离
    controls.maxDistance = 12; // 减少最大距离，保持合适的观看范围
    
    // 禁用旋转功能，只允许缩放和平移
    controls.enableRotate = false; // 禁用摄像机旋转
    
    controls.target.set(0, -0.5, 0); // 设置控制器目标为柜台上的手机位置
    controlsRef.current = controls;
    
    // 延迟设置摄像机位置，确保在模型加载后应用
    setTimeout(() => {
      camera.position.set(0, 2, 8);
      controls.update();
    }, 100);

    // 创建光照系统
    const ambientLight = new THREE.AmbientLight(0x404040, 0.8);
    scene.add(ambientLight);

    // 主光源
    const mainLight = new THREE.DirectionalLight(0xffffff, 1.5);
    mainLight.position.set(5, 10, 5);
    mainLight.castShadow = true;
    mainLight.shadow.mapSize.width = 2048;
    mainLight.shadow.mapSize.height = 2048;
    scene.add(mainLight);
    
    // 添加聚光灯（模拟展示灯）
    const spotLight1 = new THREE.SpotLight(0xffffff, 1.0, 100, Math.PI / 6, 0.1);
    spotLight1.position.set(0, 8, 0);
    spotLight1.target.position.set(0, 0, 0);
    spotLight1.castShadow = true;
    scene.add(spotLight1);
    scene.add(spotLight1.target);
    
    // 添加多个点光源增强亮度
    const pointLights: Array<{ position: [number, number, number], intensity: number }> = [
      { position: [-10, 10, 10], intensity: 0.6 },
      { position: [10, -10, 10], intensity: 0.5 },
      { position: [0, 0, -10], intensity: 0.4 },
      { position: [5, 5, 5], intensity: 0.3 }
    ];

    pointLights.forEach(light => {
      const pointLight = new THREE.PointLight(0xffffff, light.intensity, 100);
      pointLight.position.set(...light.position);
      scene.add(pointLight);
    });

    // 加载真实GLTF部件模型
    const gltfLoader = new GLTFLoader();
    const phoneGroup = new THREE.Group();
    modelRef.current = phoneGroup;

    const parts: PhonePart[] = [];
    let loadedPartsCount = 0;
    const totalParts = 5;

    // 定义各部件的配置
    const partConfigs = [
      {
        path: './module/screen.gltf',
        name: 'screen',
        position: new THREE.Vector3(0, 0, 0), // 屏幕稍微向前
        scale: new THREE.Vector3(0.06, 0.06, 0.06),
        disassemblyOrder: 2,
        animationOffset: new THREE.Vector3(0, 0, -1.2)
      },
      {
        path: './module/case.gltf',
        name: 'backCover',
        position: new THREE.Vector3(0, 0, 0), // 后盖稍微向后
        scale: new THREE.Vector3(0.06, 0.06, 0.06),
        disassemblyOrder: 1,
        animationOffset: new THREE.Vector3(0, 0, 1.2)
      },
      {
        path: './module/carrema.gltf',
        name: 'camera',
        position: new THREE.Vector3(0, 0.07, 0), // 摄像头位置调整到屏幕上方
        scale: new THREE.Vector3(5.5, 5.5, 5.5),
        disassemblyOrder: 4,
        animationOffset: new THREE.Vector3(0, 0.8, 0.4)
      },
      {
        path: './module/band.gltf',
        name: 'mainBoard',
        position: new THREE.Vector3(0, 0, 0), // 主板稍微向下并向前
        scale: new THREE.Vector3(6.0, 6.0, 6.0),
        disassemblyOrder: 5,
        animationOffset: new THREE.Vector3(0.6, 0, 0)
      },
      {
        path: './module/battery.gltf',
        name: 'battery',
        position: new THREE.Vector3(0, 0, 0.01), // 电池位置向下并稍微向后
        scale: new THREE.Vector3(0.06, 0.06, 0.06),
        disassemblyOrder: 3,
        animationOffset: new THREE.Vector3(0, -0.8, 0)
      }
    ];

    // 加载每个部件
    partConfigs.forEach((config, index) => {
      console.log(`开始加载部件: ${config.name} (${config.path})`);

      gltfLoader.load(
        config.path,
        (gltf) => {
          console.log(`${config.name} 加载成功`);

          const model = gltf.scene;

          // 调整模型位置、大小和旋转
          model.position.copy(config.position);
          model.scale.copy(config.scale);

          // 确保模型可见性和阴影
          model.traverse((child) => {
            if (child instanceof THREE.Mesh) {
              child.castShadow = true;
              child.receiveShadow = true;

              // 特别处理摄像头和主板的可见性
              if (config.name === 'camera' || config.name === 'mainBoard') {
                child.renderOrder = 1; // 提高渲染优先级
              }

              // 确保材质可见
              if (child.material) {
                if (Array.isArray(child.material)) {
                  child.material.forEach(mat => {
                    if (mat instanceof THREE.MeshStandardMaterial || mat instanceof THREE.MeshPhongMaterial) {
                      mat.transparent = false;
                      mat.opacity = 1.0;
                      
                      // 特殊处理屏幕材质
                      if (config.name === 'screen') {
                        mat.side = THREE.DoubleSide; // 双面渲染
                        mat.emissive = new THREE.Color(0x222222); // 轻微发光增强可见性
                        if (mat instanceof THREE.MeshStandardMaterial) {
                          mat.metalness = 0.1;
                          mat.roughness = 0.3;
                          // 只对 MeshStandardMaterial 设置 envMapIntensity
                          mat.envMapIntensity = 1.5;
                        }
                      }
                      
                      // 为摄像头和主板增强材质
                      if (config.name === 'camera') {
                        mat.emissive = new THREE.Color(0x111111); // 轻微发光
                      }
                      if (config.name === 'mainBoard' && mat instanceof THREE.MeshStandardMaterial) {
                        mat.metalness = 0.8;
                        mat.roughness = 0.2;
                      }
                    }
                  });
                } else if (child.material instanceof THREE.MeshStandardMaterial || child.material instanceof THREE.MeshPhongMaterial) {
                  child.material.transparent = false;
                  child.material.opacity = 1.0;
                  
                  // 特殊处理屏幕材质
                  if (config.name === 'screen') {
                    child.material.side = THREE.DoubleSide; // 双面渲染
                    child.material.emissive = new THREE.Color(0x222222); // 轻微发光增强可见性
                    if (child.material instanceof THREE.MeshStandardMaterial) {
                      child.material.metalness = 0.1;
                      child.material.roughness = 0.3;
                      // 只对 MeshStandardMaterial 设置 envMapIntensity
                      child.material.envMapIntensity = 1.5;
                    }
                  }
                  
                  // 为摄像头和主板增强材质
                  if (config.name === 'camera') {
                    child.material.emissive = new THREE.Color(0x111111);
                  }
                  if (config.name === 'mainBoard' && child.material instanceof THREE.MeshStandardMaterial) {
                    child.material.metalness = 0.8;
                    child.material.roughness = 0.2;
                  }
                }
              }
            }
          });

          // 创建部件信息
          const part: PhonePart = {
            id: `${config.name}_${index}`,
            name: config.name,
            mesh: model,
            originalPosition: config.position.clone(),
            disassemblyOrder: config.disassemblyOrder,
            animationOffset: config.animationOffset
          };

          parts.push(part);
          phoneGroup.add(model);

          loadedPartsCount++;
          console.log(`已加载 ${loadedPartsCount}/${totalParts} 个部件`);

          // 所有部件加载完成
          if (loadedPartsCount === totalParts) {
            phonePartsRef.current = parts.sort((a, b) => a.disassemblyOrder - b.disassemblyOrder);

            // 调整整体模型大小和位置
            phoneGroup.scale.setScalar(1.5); // 放大模型1.5倍
            phoneGroup.position.set(0, 0, 0);
            
            // 旋转手机模型，让屏幕朝向摄像机
            phoneGroup.rotation.y = Math.PI; // 旋转180度，让屏幕面向摄像机

            // 计算模型边界框用于参考，但保持我们设定的摄像机位置
            const box = new THREE.Box3().setFromObject(phoneGroup);
            const center = box.getCenter(new THREE.Vector3());
            const size = box.getSize(new THREE.Vector3());

            // 保持我们设定的摄像机位置，不要被模型加载后重置
            camera.position.set(-2.5, 5, -8); // 从背面观看，实现180度旋转视角
            camera.lookAt(0, -0.5, 0); // 看向手机位置
            
            // 设置手机模型的初始旋转（180度）
            phoneGroup.rotation.y = Math.PI;
            phoneRotationRef.current.y = Math.PI; // 同步旋转状态
            
            // 更新控制器
            if (controlsRef.current) {
              controlsRef.current.update();
            }

            scene.add(phoneGroup);
            setModelLoaded(true);

            console.log('模型加载完成！', {
              center: center,
              size: size,
              cameraPosition: camera.position,
              parts: parts.map(p => p.name)
            });
          }
        },
        (progress) => {
          if (progress.total > 0) {
            const percent = (progress.loaded / progress.total * 100).toFixed(1);
            console.log(`${config.name} 加载进度: ${percent}%`);
          }
        },
        (error) => {
          console.error(`${config.name} 加载失败:`, error);

          // 如果某个部件加载失败，仍然继续
          loadedPartsCount++;
          if (loadedPartsCount === totalParts) {
            phonePartsRef.current = parts.sort((a, b) => a.disassemblyOrder - b.disassemblyOrder);
            phoneGroup.scale.setScalar(2);
            scene.add(phoneGroup);
            setModelLoaded(true);
            console.log('部分部件加载完成，继续使用已加载的部件');
          }
        }
      );
    });

    // 点击事件处理 - 显示部件详细信息
    const handleClick = (event: MouseEvent) => {
      // 如果刚刚进行了拖拽，不处理点击事件
      if (hasDragged) {
        return;
      }
      
      if (!modelLoaded || !modelRef.current || isAnimating) {
        return;
      }

      const rect = renderer.domElement.getBoundingClientRect();
      mouseRef.current.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      mouseRef.current.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

      raycasterRef.current.setFromCamera(mouseRef.current, camera);

      const allMeshes: THREE.Object3D[] = [];
      modelRef.current.traverse((child) => {
        if (child instanceof THREE.Mesh) {
          allMeshes.push(child);
        }
      });

      const intersects = raycasterRef.current.intersectObjects(allMeshes, false);

      if (intersects.length > 0) {
        const clickedMesh = intersects[0].object;
        
        const clickedPart = phonePartsRef.current.find(part => {
          let found = false;
          part.mesh.traverse((child) => {
            if (child === clickedMesh) {
              found = true;
            }
          });
          return found;
        });

        if (clickedPart) {
          setSelectedPart(clickedPart);
          setShowPartInfo(true);
        }
      } else {
        setShowPartInfo(false);
        setSelectedPart(null);
      }
    };

    // 添加事件监听器
    renderer.domElement.addEventListener('click', handleClick);
    
    // 添加鼠标拖拽事件监听器
    let isMouseDown = false;
    let lastMousePosition = { x: 0, y: 0 };
    
    const handleMouseDown = (event: MouseEvent) => {
      isMouseDown = true;
      setHasDragged(false);
      lastMousePosition = { x: event.clientX, y: event.clientY };
      // 不阻止默认事件，让点击事件能正常触发
    };
    
    const handleMouseMove = (event: MouseEvent) => {
      if (!isMouseDown || !modelRef.current) return;
      
      const deltaMove = {
        x: event.clientX - lastMousePosition.x,
        y: event.clientY - lastMousePosition.y
      };
      
      // 如果移动距离超过阈值，认为是拖拽
      if (Math.abs(deltaMove.x) > 3 || Math.abs(deltaMove.y) > 3) {
        setHasDragged(true);
        
        // 计算旋转角度（调整灵敏度）
        const rotationSpeed = 0.01;
        phoneRotationRef.current.y += deltaMove.x * rotationSpeed;
        // 禁用X轴旋转，只允许横向旋转
        // phoneRotationRef.current.x += deltaMove.y * rotationSpeed;
        
        // 应用旋转到手机模型（只旋转Y轴）
        modelRef.current.rotation.y = phoneRotationRef.current.y;
        // 保持X轴旋转为0
        modelRef.current.rotation.x = 0;
        
        lastMousePosition = { x: event.clientX, y: event.clientY };
      }
    };
    
    const handleMouseUp = () => {
      isMouseDown = false;
      // 立即重置拖拽标志，但给点击事件一个短暂的处理时间
      setTimeout(() => {
        setHasDragged(false);
      }, 50);
    };
    
    // 添加事件监听器
    renderer.domElement.addEventListener('mousedown', handleMouseDown);
    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);
    
    // 渲染循环动画循环
    // 添加AR支持
    if ('xr' in navigator) {
      renderer.xr.enabled = true;

      // 创建AR按钮
      const arButton = ARButton.createButton(renderer, {
        requiredFeatures: ['hit-test'],
        optionalFeatures: ['dom-overlay'],
        domOverlay: { root: document.body }
      });

      arButton.style.position = 'absolute';
      arButton.style.bottom = '20px';
      arButton.style.right = '20px';
      arButton.style.padding = '12px 24px';
      arButton.style.background = '#007AFF';
      arButton.style.color = 'white';
      arButton.style.border = 'none';
      arButton.style.borderRadius = '25px';
      arButton.style.fontSize = '16px';
      arButton.style.fontWeight = 'bold';
      arButton.style.cursor = 'pointer';
      arButton.textContent = '启动AR模式';

      mountRef.current.appendChild(arButton);
      arButtonRef.current = arButton;

      // AR会话开始/结束事件
      renderer.xr.addEventListener('sessionstart', () => {
        setIsARMode(true);
        console.log('AR会话开始');
      });

      renderer.xr.addEventListener('sessionend', () => {
        setIsARMode(false);
        console.log('AR会话结束');
      });

      // 添加手部控制器支持
      const controllerModelFactory = new XRControllerModelFactory();

      const controller1 = renderer.xr.getController(0);
      controller1.addEventListener('selectstart', onSelectStart);
      controller1.addEventListener('selectend', onSelectEnd);
      scene.add(controller1);

      const controllerGrip1 = renderer.xr.getControllerGrip(0);
      controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1));
      scene.add(controllerGrip1);

      controllerRef.current = controller1;
    }

    renderLoop = () => {
      renderer.setAnimationLoop(renderLoop);
      
      // 更新OrbitControls
      if (controlsRef.current) {
        controlsRef.current.update();
      }

      // 注释掉自动旋转，避免干扰视角
      // if (modelRef.current && !isAnimating && !isARMode) {
      //   modelRef.current.rotation.y += 0.003;
      // }

      renderer.render(scene, camera);
    };
    renderLoop();

    // 窗口大小调整
    const handleResize = () => {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    };
    window.addEventListener('resize', handleResize);

    // 清理函数
    return () => {
      if (animationIdRef.current) {
        cancelAnimationFrame(animationIdRef.current);
      }

      renderer.domElement.removeEventListener('click', handleClick);
      renderer.domElement.removeEventListener('mousedown', handleMouseDown);
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
      window.removeEventListener('resize', handleResize);
      
      // 清理OrbitControls
      if (controlsRef.current) {
        controlsRef.current.dispose();
      }

      if (mountRef.current && renderer.domElement) {
        mountRef.current.removeChild(renderer.domElement);
      }

      renderer.dispose();
    };
  }, []);

  // 手动控制拆解步骤
  const handleStepControl = (step: number) => {
    if (isAnimating || !modelLoaded) return;

    if (step === 0) {
      // 重置
      resetAnimation();
    } else if (step > disassemblyStep) {
      // 前进到指定步骤
      setDisassemblyStep(step);
      animateDisassembly(step);
    }
  };

  const getStepText = () => {
    const steps = [
      modelLoaded ? '使用下方按钮进行步骤拆解，点击部件查看详细信息' : '正在加载模型...',
      '第1步：后盖已拆除 - 点击部件查看详细信息',
      '第2步：屏幕已拆除 - 点击部件查看详细信息',
      '第3步：电池已拆除 - 点击部件查看详细信息',
      '第4步：拆解完成 - 只剩主板，点击查看详细信息'
    ];
    return steps[disassemblyStep] || '拆解完成';
  };

  const getPartsByStep = (step: number) => {
    return phonePartsRef.current.filter(part => part.disassemblyOrder === step);
  };

  // 获取部件详细信息
  const getPartDetails = (part: PhonePart) => {
    const partDetails: { [key: string]: any } = {
      'case': {
        name: '手机后盖',
        description: 'iPhone采用精密加工的铝合金一体式后盖，集成无线充电线圈、NFC天线和散热结构。后盖通过精密的卡扣和胶条密封，提供IP68级防水防尘保护。',
        material: '航空级铝合金/玻璃纤维',
        function: '结构保护、无线充电、散热、防水密封、天线集成',
        disassemblyTips: '使用专用撬棒从底部开始，先加热软化密封胶，小心断开无线充电排线'
      },
      'screen': {
        name: '显示屏总成',
        description: 'iPhone采用Super Retina XDR OLED显示屏，集成3D Touch/Haptic Touch压感技术、True Tone显示技术和前置摄像头模组。屏幕总成包含显示面板、触控层、背光模组和前置传感器阵列。',
        material: 'OLED面板、康宁大猩猩玻璃、铝合金边框',
        function: '图像显示、多点触控、压感检测、环境光感应、距离感应',
        disassemblyTips: '先断开电池，使用热风枪加热边缘，小心撬开屏幕，注意保护排线连接器'
      },
      'battery': {
        name: '锂离子电池',
        description: 'iPhone使用定制的L型锂离子聚合物电池，采用先进的电池管理系统和快充技术。电池通过强力胶条固定，支持无线充电和MagSafe磁吸充电。',
        material: '锂离子聚合物、铝箔封装',
        function: '电能存储、快速充电、无线充电、电源管理、温度监控',
        disassemblyTips: '断开电池排线后，小心拉取胶条，避免弯折电池，注意防止短路'
      },
      'band': {
        name: '中框总成',
        description: 'iPhone的精密加工铝合金中框，集成天线系统、按键组件、扬声器网罩和Lightning/USB-C接口。中框承载整机结构强度，并作为散热和电磁屏蔽的重要组成部分。',
        material: '航空级铝合金、不锈钢',
        function: '结构支撑、天线载体、按键集成、接口保护、电磁屏蔽、散热',
        disassemblyTips: '注意天线连接点和按键排线，使用专用工具拆卸螺丝，避免损坏精密结构'
      },
      'carrema': {
        name: '摄像头模组',
        description: 'iPhone采用多摄像头系统，包含主摄、超广角、长焦镜头和LiDAR扫描仪。每个镜头都配备光学防抖、自动对焦和先进的图像信号处理器，支持4K视频录制和计算摄影功能。',
        material: '蓝宝石玻璃镜头、钛合金框架、精密马达',
        function: '图像捕捉、光学防抖、自动对焦、深度感知、夜景模式、人像模式',
        disassemblyTips: '先断开排线连接，小心取出镜头模组，避免震动损坏防抖系统'
      },
      'scene': {
        name: '主板(逻辑板)',
        description: 'iPhone的多层PCB主板集成了A系列仿生芯片、内存、存储控制器、电源管理IC、基带芯片等核心组件。采用先进的封装技术和散热设计，实现高性能和低功耗的完美平衡。',
        material: '多层PCB、硅芯片、陶瓷封装',
        function: 'CPU/GPU处理、内存管理、存储控制、电源管理、通信处理、传感器集成',
        disassemblyTips: '最后拆卸，先断开所有排线连接，注意静电防护，避免触碰芯片表面'
      }
    };

    // 创建名称映射，将部件名称映射到详细信息的key
     const nameMapping: { [key: string]: string } = {
       'screen': 'screen',
       'backCover': 'case',
       'camera': 'carrema', 
       'mainBoard': 'scene',
       'battery': 'battery'
     };

    // 首先尝试通过名称映射查找
     let partKey: string | undefined = nameMapping[part.name];
     
     // 如果映射失败，尝试通过ID包含关系查找
     if (!partKey) {
       partKey = Object.keys(partDetails).find(key => part.id.toLowerCase().includes(key));
     }
    
    const details = partKey ? partDetails[partKey] : null;

    return {
      name: details?.name || part.name || part.id,
      description: details?.description || '暂无详细描述',
      material: details?.material || '未知材质',
      function: details?.function || '基本功能',
      disassemblyTips: details?.disassemblyTips || '请谨慎操作'
    };
  };

  // 如果是小程序环境，直接返回空白页面
  if (isMiniProgram()) {
    return <View className="access-restricted"></View>;
  }

  return (
    <View className="phone-model-container">
      <div ref={mountRef} className="three-canvas" />
      


      {/* 隐藏的视频元素用于手势识别 */}
      <video
        ref={videoRef}
        style={{
          position: 'absolute',
          top: '-9999px',
          width: '320px',
          height: '240px'
        }}
        muted
        playsInline
      />



      {/* 部件详细信息面板 */}
      {showPartInfo && selectedPart && (
        <View className="part-info-panel" style={{
          position: 'absolute',
          top: '20px',
          left: '20px',
          width: '300px',
          maxHeight: '400px',
          background: 'rgba(255, 255, 255, 0.95)',
          borderRadius: '10px',
          boxShadow: '0 4px 20px rgba(0, 0, 0, 0.3)',
          zIndex: 1000,
          overflow: 'hidden',
          backdropFilter: 'blur(10px)'
        }}>
          <View className="part-info-header" style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            padding: '15px 20px',
            background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
            color: 'white'
          }}>
            <Text className="part-info-title" style={{
              fontSize: '18px',
              fontWeight: 'bold',
              margin: '0'
            }}>{getPartDetails(selectedPart).name}</Text>
            <button 
              className="close-btn"
              style={{
                background: 'none',
                border: 'none',
                color: 'white',
                fontSize: '24px',
                cursor: 'pointer',
                padding: '0',
                width: '30px',
                height: '30px',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                borderRadius: '50%',
                transition: 'background-color 0.2s'
              }}
              onClick={() => {
                setShowPartInfo(false);
                setSelectedPart(null);
              }}
            >
              ×
            </button>
          </View>
          <View className="part-info-content" style={{
            padding: '20px',
            maxHeight: '320px',
            overflowY: 'auto'
          }}>
            <View className="info-item" style={{ marginBottom: '15px' }}>
              <Text className="info-label" style={{
                fontWeight: 'bold',
                color: '#333',
                fontSize: '14px',
                marginBottom: '5px',
                display: 'block'
              }}>描述：</Text>
              <Text className="info-value" style={{
                color: '#666',
                fontSize: '14px',
                lineHeight: '1.5',
                display: 'block'
              }}>{getPartDetails(selectedPart).description}</Text>
            </View>
            <View className="info-item" style={{ marginBottom: '15px' }}>
              <Text className="info-label" style={{
                fontWeight: 'bold',
                color: '#333',
                fontSize: '14px',
                marginBottom: '5px',
                display: 'block'
              }}>材质：</Text>
              <Text className="info-value" style={{
                color: '#666',
                fontSize: '14px',
                lineHeight: '1.5',
                display: 'block'
              }}>{getPartDetails(selectedPart).material}</Text>
            </View>
            <View className="info-item" style={{ marginBottom: '15px' }}>
              <Text className="info-label" style={{
                fontWeight: 'bold',
                color: '#333',
                fontSize: '14px',
                marginBottom: '5px',
                display: 'block'
              }}>功能：</Text>
              <Text className="info-value" style={{
                color: '#666',
                fontSize: '14px',
                lineHeight: '1.5',
                display: 'block'
              }}>{getPartDetails(selectedPart).function}</Text>
            </View>
            <View className="info-item" style={{ marginBottom: '0' }}>
              <Text className="info-label" style={{
                fontWeight: 'bold',
                color: '#333',
                fontSize: '14px',
                marginBottom: '5px',
                display: 'block'
              }}>拆解提示：</Text>
              <Text className="info-value" style={{
                color: '#666',
                fontSize: '14px',
                lineHeight: '1.5',
                display: 'block'
              }}>{getPartDetails(selectedPart).disassemblyTips}</Text>
            </View>
          </View>
        </View>
      )}

      {/* 控制面板 */}
      <View className="controls-panel">
        <View className="status-info">
          <Text className="status-text">{getStepText()}</Text>
          <Text className="parts-count">模型部件数: {phonePartsRef.current.length}</Text>
          {isAnimating && <Text className="animating-text">动画进行中...</Text>}
        </View>

        {/* 步骤控制按钮 */}
        <View className="step-controls">
          <button
            className={`step-btn ${disassemblyStep === 0 ? 'active' : ''}`}
            onClick={() => handleStepControl(0)}
            disabled={isAnimating}
          >
            重置
          </button>
          {[1, 2, 3, 4].map(step => (
            <button
              key={step}
              className={`step-btn ${disassemblyStep === step ? 'active' : ''}`}
              onClick={() => handleStepControl(step)}
              disabled={isAnimating || !modelLoaded}
            >
              步骤{step}
            </button>
          ))}
        </View>

        {/* 部件信息 */}
        <View className="parts-info">
          <Text>当前拆解部件:</Text>
          {disassemblyStep > 0 && getPartsByStep(disassemblyStep).map(part => (
            <Text key={part.id} className="part-item">
              • {part.name} ({part.id})
            </Text>
          ))}
        </View>

        {/* 操作提示 */}
        <View className="instructions">
          <Text>🖱️ 拖拽旋转 | 🔄 滚轮缩放 | 📱 右键平移</Text>
        </View>
      </View>

    </View>
  );
};

export default PhoneModel;







